﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace TaskEditor
{
    public class ZMyNode : TreeNode
    {
        private readonly string zFieldName;
        private readonly string zDes;
        private object zParent;
        private FieldInfo zFieldInfo;
        private IList zList;
        private int zArrayIndex = -1;
        private object zValue;
        public string zStringValue { get; private set; }
        public void zRefresh()
        {
            Nodes.Clear();
            Type type = zValue.GetType();
            if (zList!=null && zArrayIndex==-1)
            {
                Type eletype = zList.GetType().GetElementType();
                if (eletype==null)
                {
                    eletype = zList.GetType().GetGenericArguments()[0];
                }
                if (eletype.FullName.Contains("System"))
                {
                    zStringValue = "";
                    for (int i = 0; i < zList.Count; i++)
                    {
                        zStringValue += zList[i] + " ";
                    }
                }
                else
                {
                    for (int i = 0; i < zList.Count; i++)
                    {
                        ZMyNode node = new ZMyNode(zList[i], $"[{i}]")
                        {
                            zList = zList,
                            zArrayIndex = i
                        };
                        Nodes.Add(node);
                    }
                }
            }
            else
            {
                if (!type.FullName.StartsWith("System"))
                {
                    var mens = type.GetFields();
                    foreach (var field in mens)
                    {
                        object value = field.GetValue(zValue);
                        ZMyNode node = new ZMyNode(value, field.Name)
                        {
                            zParent = zValue,
                            zFieldInfo = field
                        };
                        Nodes.Add(node);
                    }
                }
                else
                {
                    zStringValue = zValue.ToString();
                }
            }
            if (zStringValue != null)
            {
                Text = zDes + ":" + zStringValue;
            }
        }
        public ZMyNode(object obj, string fieldname)
        {
            zValue = obj;
            zFieldName = fieldname;

            Type type = zValue.GetType();
            zDes = $"<{type.Name}> {zFieldName}";
            if (type.IsArray || type.Name.StartsWith("List"))
            {
                zList = zValue as IList;
                zDes += "[" + zList.Count + "]";
                Text = zDes;
            }
            else if (type.FullName.StartsWith("System"))
            {
                Text =zDes+ ":" + zValue;
            }
            else
            {
                Text = zDes;
            }
        }

        private object transLateType(string value, Type type)
        {
            switch (type.Name)
            {
                case "UInt16":
                    return ushort.Parse(value);
                case "UInt32":
                    return uint.Parse(value);
                case "Int32":
                    return int.Parse(value);
                case "Int16":
                    return ushort.Parse(value);
                case "Byte":
                    return byte.Parse(value);
                case "Single":
                    return float.Parse(value);
                case "Boolean":
                    return bool.Parse(value);
            }
            return value;
        }
        public void zSetValue(string value)
        {
            if (zList != null)
            {
                Type ele = zList.GetType().GetElementType();
                if (ele == null)
                {
                    ele = zList.GetType().GetGenericArguments()[0];
                }
                if (zArrayIndex == -1)
                {
                    string[] pms = value.Split(' ');
                    for (int i = 0; i < zList.Count; i++)
                    {
                        object evalue = transLateType(pms[i], ele);
                        zList[i] = evalue;
                    }
                }
                else
                {
                    zValue = transLateType(value, ele);
                    zList[zArrayIndex] = zValue;
                }
            }
            else if (zParent != null)
            {
                zValue = transLateType(value, zFieldInfo.FieldType);
                zFieldInfo.SetValue(zParent, zValue);
            }
            zRefresh();
        }

    }

}
